
package networkSimulation.visualisation.graph.graphviz

import networkSimulation.simulator.Simulator
import networkSimulation.framework._
import java.io.File

/**
 * This trait can be added to any simulator that uses Directed or Undirected Graphs
 * to support visualisation with the GraphViz framework.
 *
 * @author  Tim Caljé
 *          Jeroen De Raedt
 *          Jorick Van Aken
 */
trait GraphvizVisualiser[N,E] extends Simulator[N,E]{
  /**
   * The visualiser that will transform the textual representation of the graph into an image of the graph
   */
  private val visualiser = new Visualiser()

  /**
   * The basic shape of the nodes in the graph
   */
  var shape = "circle"

  /**
   * Transform the graph into 2 textual strings.
   *
   * 1 string will represent all nodes of the graph
   * 1 string will represent the edges of the graph
   *
   * @param outputpath
   *        The path were the image of the graph will be stored
   */
  def saveVisualGraph(outputPath : String) = {   

    var nodesString = ""
    var edgesString = ""

    for(n: Node <- graph.nodes.map(_.asInstanceOf[Node]).toList) {
      nodesString += ";[color=" + n.getColor + " ,style=filled,shape=" + shape + "]" + n.name
    }

    for(e: Edge[Node] <- graph.edges.map(_.asInstanceOf[Edge[Node]]).toList) {
      edgesString += ";" + e.from.name + " -> " + e.to.name + " [" + getDirection + " color=\"" + e.getColor + "\"]"
    }

    visualiser.saveGraph(nodesString,edgesString,outputPath)

  }

  /**
   * This method returns the textual representation of either a directed Edge or an Undirected Edge
   * which is based on the current type of graph.
   *
   * @throws  IllegalStateException
   *          If the graph is no Directed or Undirected Graph, an IllegalStateException will be thrown.
   */
  private def getDirection() = graph match {
    case UndirectedGraph() => "dir=none"
    case DirectedGraph() => ""
    case _ => throw new Exception("Unknown graph-type")
  }
}

